/*
 * Copyright (C) 2019-2020 Alibaba Group Holding Limited
 */


#include <stdlib.h>
#include <string.h>
#include <aos/aos.h>
#include <cJSON.h>
#include "app_main.h"

#define TAG "appiot"

#if defined(CONFIG_IR_DEMO) && CONFIG_IR_DEMO
enum iot_property {
    IOT_PROP_AC_LEARN = 1,
    IOT_PROP_AC_ONOFF,
    IOT_PROP_AC_MODE,
    IOT_PROP_AC_TEMP,
    IOT_PROP_AC_WIND_DIRECT,
    IOT_PROP_AC_WIND_POWER,
};

enum ac_mode {
    AC_MODE_COOL,
    AC_MODE_HOT,
    AC_MODE_DEHUM,
    AC_MODE_WIND,
};

enum ac_wind_direct {
    AC_WIND_DIR_UPDOWN,
    AC_WIND_DIR_CLOSE,
};

enum ac_wind_power {
    AC_WIND_POW_LOW,
    AC_WIND_POW_MEDIUM,
    AC_WIND_POW_HIGH,
    AC_WIND_POW_AUTO,
};

static iotdispatcher_config_t iot_configs[] = {
    {0, IOT_PROP_AC_LEARN,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "匹配空调"},
    {0, IOT_PROP_AC_ONOFF,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "打开空调",     1},
    {0, IOT_PROP_AC_ONOFF,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "关闭空调",     0},
    {0, IOT_PROP_AC_MODE,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "制冷模式",     AC_MODE_COOL},
    {0, IOT_PROP_AC_MODE,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "加热模式",     AC_MODE_HOT},
    {0, IOT_PROP_AC_MODE,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "抽湿模式",     AC_MODE_DEHUM},
    {0, IOT_PROP_AC_MODE,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "送风模式",     AC_MODE_WIND},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_STRING,     "调高温度",     (iot_value_t)"up"},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_STRING,     "调低温度",     (iot_value_t)"down"},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "十六度",     16},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "十七度",     17},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "十八度",     18},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "十九度",     19},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十度",     20},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十一度",   21},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十二度",   22},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十三度",   23},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十四度",   24},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十五度",   25},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十六度",   26},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十七度",   27},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十八度",   28},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "二十九度",   29},
    {0, IOT_PROP_AC_TEMP,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "三十度",     30},
    {0, IOT_PROP_AC_WIND_DIRECT, IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "上下摆风",   AC_WIND_DIR_UPDOWN},
    {0, IOT_PROP_AC_WIND_DIRECT, IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "停止摆风",   AC_WIND_DIR_CLOSE},
    {0, IOT_PROP_AC_WIND_POWER,  IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "最小风量",   AC_WIND_POW_LOW},
    {0, IOT_PROP_AC_WIND_POWER,  IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "中等风量",   AC_WIND_POW_MEDIUM},
    {0, IOT_PROP_AC_WIND_POWER,  IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "最大风量",   AC_WIND_POW_HIGH},
    {0, IOT_PROP_AC_WIND_POWER,  IOT_SRC_VOICE,          IOT_TYPE_VALUE,        "自动风量",   AC_WIND_POW_AUTO},
};

static void iot_user_cb(iot_src_e src, int property)
{
    LOGD(TAG, "iot user cb %d %d", src, property);
    int ret;

    mvoice_process_pause();

    switch (property) {
        case IOT_PROP_AC_LEARN: {
            extern unsigned char match_remote_flag;

            match_remote_flag = 1;
            local_audio_play("请按空调遥控器电源键", 0);
            
            while(match_remote_flag)
            {
                match_remote_process();
            }
            break;
        }

        case IOT_PROP_AC_ONOFF: {
            int ac_onoff;
            if (iotdispatcher_get_int_result(&ac_onoff) == 0) {
                if (ac_onoff) {
                    asr_ir_deal(ASR_DA_KAI_KONG_TIAO);
                } else {
                    asr_ir_deal(ASR_GUAN_BI_KONG_TIAO);
                }
            }
            break;
        }

        case IOT_PROP_AC_MODE: {
            int ac_mode;
            if (iotdispatcher_get_int_result(&ac_mode) == 0) {
                switch(ac_mode) {
                    case AC_MODE_COOL:
                        asr_ir_deal(ASR_ZHI_LENG_MO_SHI);
                        break;
                    case AC_MODE_HOT:
                        asr_ir_deal(ASR_JIA_RE_MO_SHI);
                        break;
                    case AC_MODE_DEHUM:
                        asr_ir_deal(ASR_CHOU_SHI_MO_SHI);
                        break;
                    case AC_MODE_WIND:
                        asr_ir_deal(ASR_SONG_FENG_MO_SHI);
                        break;
                    default:
                        break;
                }
            }
            break;
        }

        case IOT_PROP_AC_WIND_DIRECT: {
            int ac_wind_dir;
            if (iotdispatcher_get_int_result(&ac_wind_dir) == 0) {
                switch(ac_wind_dir) {
                    case AC_WIND_DIR_UPDOWN:
                        asr_ir_deal(ASR_SHANG_XIA_BAI_FENG);
                        break;
                    case AC_WIND_DIR_CLOSE:
                        asr_ir_deal(ASR_TING_ZHI_BAI_FENG);
                        break;
                    default:
                        break;
                }
            }
            break;
        }

        case IOT_PROP_AC_WIND_POWER: {
            int ac_wind_pow;
            if (iotdispatcher_get_int_result(&ac_wind_pow) == 0) {
                switch(ac_wind_pow) {
                    case AC_WIND_POW_LOW:
                        asr_ir_deal(ASR_ZUI_XIAO_FENG_LIANG);
                        break;
                    case AC_WIND_POW_MEDIUM:
                        asr_ir_deal(ASR_ZHONG_DENG_FENG_LIANG);
                        event_air_wind_speed_mid();
                        break;
                    case AC_WIND_POW_HIGH:
                        asr_ir_deal(ASR_ZUI_DA_FENG_LIANG);
                        event_air_wind_speed_max();
                        break;
                    case AC_WIND_POW_AUTO:
                        asr_ir_deal(ASR_ZI_DONG_FENG_LIANG);
                        event_air_wind_speed_auto();
                        break;
                    default:
                        break;
                }
            }
            break;
        }

        case IOT_PROP_AC_TEMP: {
            if (iotdispatcher_result_is_string()) {
                const char *cmd;
                if (iotdispatcher_get_string_result(&cmd) == 0) {
                    if (strcmp(cmd, "up") == 0) {
                        asr_ir_deal(ASR_TIAO_GAO_WEN_DU);
                    } else {
                        asr_ir_deal(ASR_TIAO_DI_WEN_DU);
                    }
                }
            } else {
                int temp;
                if (iotdispatcher_get_int_result(&temp) == 0) {
                    asr_set_temparature(temp);
                }
            }
            break;
        }

        default: break;
    }

    extern unsigned char f_asr_response;
    local_audio_array_play(f_asr_response, 0);
    mvoice_process_resume();
}
#else
enum iot_property {
    IOT_PROP_LED_SWITCH = 1,
    IOT_PROP_LED_BRIGHTNESS,
    IOT_PROP_LED_RGB,
    IOT_PROP_LED_YELLOW,
    IOT_PROP_LED_WHITE,
    IOT_PROP_LED_NATURE,
    IOT_PROP_WIFI_PROV,
};

static iotdispatcher_config_t iot_configs[] = {
    {0, IOT_PROP_LED_SWITCH,        IOT_SRC_SMARTLIVING,    IOT_TYPE_VALUE,     "powerstate"},
    {0, IOT_PROP_LED_SWITCH,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "打开灯光",     1},
    {0, IOT_PROP_LED_SWITCH,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "关闭灯光",     0},
    {0, IOT_PROP_LED_BRIGHTNESS,    IOT_SRC_SMARTLIVING,    IOT_TYPE_VALUE,     "brightness"},
    {0, IOT_PROP_LED_BRIGHTNESS,    IOT_SRC_SMARTLIVING,    IOT_TYPE_STRING,     "brightness"},
    {0, IOT_PROP_LED_RGB,           IOT_SRC_SMARTLIVING,    IOT_TYPE_OBJECT,     "RGBColor"},
#ifdef NLU_USE_STRING
    {0, IOT_PROP_LED_BRIGHTNESS,    IOT_SRC_VOICE,          IOT_TYPE_STRING,    "调亮灯光",      "up"},
    {0, IOT_PROP_LED_BRIGHTNESS,    IOT_SRC_VOICE,          IOT_TYPE_STRING,    "调暗灯光",      "down"},
#else
    {0, IOT_PROP_LED_BRIGHTNESS,    IOT_SRC_VOICE,          IOT_TYPE_DELTA,     "调亮灯光",      20},
    {0, IOT_PROP_LED_BRIGHTNESS,    IOT_SRC_VOICE,          IOT_TYPE_DELTA,     "调亮一点",      20},
    {0, IOT_PROP_LED_BRIGHTNESS,    IOT_SRC_VOICE,          IOT_TYPE_DELTA,     "调暗灯光",      -20},
    {0, IOT_PROP_LED_BRIGHTNESS,    IOT_SRC_VOICE,          IOT_TYPE_DELTA,     "调暗一点",      -20},
#endif
    {0, IOT_PROP_LED_YELLOW,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "调到黄光",      -20},
    {0, IOT_PROP_LED_WHITE,         IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "调到白光",      -20},
    {0, IOT_PROP_LED_NATURE,        IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "调到自然光",    -20},
    // {LED_BRIGHTNESS,    IOT_SRC_VOICE,          IOT_TYPE_STATE, "调暗灯光",      50},
    {0, IOT_PROP_WIFI_PROV,    IOT_SRC_VOICE,          IOT_TYPE_VALUE,     "快捷配网"},
};

#define LED_LOWEST_BRIGHTNESS 20

static int led_brightness = 60;
static int curtain_closed = 0;

static void iot_user_cb(iot_src_e src, int property)
{
    LOGD(TAG, "iot user cb %d %d", src, property);
    mvoice_process_pause();

    switch (property) {
        case IOT_PROP_LED_SWITCH: {
            int led_on;

            if (iotdispatcher_get_int_result(&led_on) == 0) {
                if (led_on) {
                    app_pwm_led_set_brightness(led_brightness);
                } else {
                    app_pwm_led_control(0);
                }
                LOGD(TAG, "switch led %s", led_on ? "on" : "off");
            }
            break;
        }

        case IOT_PROP_LED_BRIGHTNESS: {
            if (iotdispatcher_get_int_result(&led_brightness) == 0) {
                led_brightness = led_brightness > 100 ? 100 : led_brightness < LED_LOWEST_BRIGHTNESS ? LED_LOWEST_BRIGHTNESS : led_brightness;
                app_pwm_led_set_brightness(led_brightness);
                LOGD(TAG, "set brightness to %d", led_brightness);
            }
            break;
        }

        case IOT_PROP_LED_RGB: {
            cJSON *root;
            if (iotdispatcher_get_object_result(&root) == 0) {
                cJSON *jred = cJSON_GetObjectItemCaseSensitive(root, "Red");
                cJSON *jgreen = cJSON_GetObjectItemCaseSensitive(root, "Green");
                cJSON *jblue = cJSON_GetObjectItemCaseSensitive(root, "Blue");
                if (!(jred && cJSON_IsNumber(jred) && jred->valueint <= 255 && jred->valueint >= 0\
                    && jgreen && cJSON_IsNumber(jgreen) && jgreen->valueint <= 255 && jgreen->valueint >= 0\
                    && cJSON_IsNumber(jblue) && jblue) && jblue->valueint <= 255 && jblue->valueint >= 0) {
                    LOGW(TAG, "rgb object format err");
                    return;
                }
                
                app_pwm_led_set_rgb(jred->valueint, jgreen->valueint, jblue->valueint);
                LOGD(TAG, "set brightness to %d", led_brightness);
            }
            break;
        }

        case IOT_PROP_LED_YELLOW: {
            app_pwm_led_set_yellow();
            break;
        }

        case IOT_PROP_LED_WHITE: {
            app_pwm_led_set_white();
            break;
        }

        case IOT_PROP_LED_NATURE: {
            app_pwm_led_set_nature();
            break;
        }

        case IOT_PROP_WIFI_PROV: {
            LOGD(TAG, "start ble wifi provisioning");
            extern int wifi_prov_method;
            wifi_prov_method = WIFI_PROVISION_SL_BLE;
            aos_kv_setint("wprov_method", wifi_prov_method);

            aos_kv_del("AUTH_AC_AS");
            aos_kv_del("AUTH_KEY_PAIRS");
            app_sys_set_boot_reason(BOOT_REASON_WIFI_CONFIG);
            aos_reboot();
            break;
        }

        default: break;
    }

    mvoice_process_resume();
}
#endif

int app_iot_init()
{
    return iotdispatcher_init(iot_configs, sizeof(iot_configs) / sizeof(iotdispatcher_config_t), iot_user_cb);
}
